home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Periodicals / develop / develop 10 code / LWFontUtility / UTILInstall / UTILInstall.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-08  |  8.7 KB  |  324 lines  |  [TEXT/MPS ]

  1. /*****************************************************************************************
  2.  
  3. UTILInstall.c - A teeny little program for installing UTILs into the LaserWriter Font
  4.     Utility.
  5.  
  6. Written by Bryan K. Ressler (Beaker), 10/8/91
  7.  
  8. *****************************************************************************************/
  9.  
  10. /***************************************************************************************/
  11. #include "UTILInstall.h"
  12.  
  13. /***************************************************************************************/
  14. SFReply        gLWFUReply;
  15. SFReply        gUTILReply;
  16. short        gAppRef;
  17. short        gLWFURef;
  18. short        gUTILRef;
  19. Handle        gUTILSpec;
  20. short        gUTILID;
  21. char        gEmptyStr[1] = { 0 };
  22. DialogPtr    gUpdating;
  23.  
  24. /***************************************************************************************/
  25. Boolean Init(SysEnvRec *env)
  26. {
  27.     short        err;
  28.     
  29.     InitGraf(&qd.thePort);            /* The usual Mac inits */
  30.     InitFonts();
  31.     InitWindows();
  32.     TEInit();
  33.     InitDialogs(nil);
  34.     InitCursor();
  35.     
  36.     MaxApplZone();
  37.  
  38.     err = SysEnvirons(2,env);
  39.     return(!err && env->systemVersion >= MINSYSTEM);
  40. }
  41.  
  42. /***************************************************************************************/
  43. void ErrorAlert(short strNum)
  44. {
  45.     Str255    parm;
  46.     
  47.     GetIndString(parm,ERRSTRSID,strNum);
  48.     ParamText(parm,gEmptyStr,gEmptyStr,gEmptyStr);
  49.     StopAlert(ERRALRTID,nil);
  50. }
  51.  
  52. /***************************************************************************************/
  53. Boolean    CopyResource(short srcRef,short destRef,ResType type,short id,short idDelta)
  54. {
  55.     Handle    res;
  56.     ResType    aType;
  57.     short    anID,attribs;
  58.     Str255    name;
  59.     
  60.     UseResFile(srcRef);
  61.     res = Get1Resource(type,id);
  62.     if (!res) return(false);
  63.     GetResInfo(res,&anID,&aType,name);
  64.     attribs = GetResAttrs(res);
  65.     DetachResource(res);
  66.     
  67.     UseResFile(destRef);
  68.     HNoPurge(res);
  69.     AddResource(res,type,id + idDelta,name);
  70.     WriteResource(res);
  71.     SetResAttrs(res,attribs);
  72.     
  73.     return(true);
  74. }
  75.  
  76. /***************************************************************************************/
  77. short CalcResSpace(short UTILID)
  78. {
  79.     return(UTILRESBASE + (UTILID - UTILIDBASE) * UTILSPACESIZE);
  80. }
  81.  
  82. /***************************************************************************************/
  83. Boolean InstallUTIL(short ID)
  84. {
  85.     Handle    res;
  86.     ResType    aType;
  87.     Str255    name;
  88.     ResSpec    *specs;
  89.     short    anID,numOwned,i,idDelta,attribs,itemsID,idSpace,curSpace;
  90.     
  91.     idSpace = CalcResSpace(ID);
  92.     curSpace = CalcResSpace(gUTILID);
  93.     /* First copy the UTIL itself */
  94.     idDelta = ID - gUTILID;
  95.     if (idDelta) {
  96.         /* Renumbering, so we need to write a new ResSpace into the UTIL */
  97.         UseResFile(gUTILRef);
  98.         res = Get1Resource(UTILTYPE,gUTILID);
  99.         if (!res) return(false);
  100.         GetResInfo(res,&anID,&aType,name);
  101.         attribs = GetResAttrs(res);
  102.         DetachResource(res);
  103.         
  104.         *(short *)(*res + RESSPACEOFFSET) = idSpace;
  105.         
  106.         UseResFile(gLWFURef);
  107.         HNoPurge(res);
  108.         AddResource(res,aType,ID,name);
  109.         WriteResource(res);
  110.         SetResAttrs(res,attribs);
  111.     } else if (!CopyResource(gUTILRef,gLWFURef,UTILTYPE,gUTILID,idDelta))
  112.         return(false);
  113.     
  114.     /* Now loop through the owned resources and copy them */
  115.     idDelta = idSpace - curSpace;
  116.     UseResFile(gUTILRef);
  117.     LoadResource(gUTILSpec);
  118.     MoveHHi(gUTILSpec); HLock(gUTILSpec); HNoPurge(gUTILSpec);
  119.     numOwned = **(short **)gUTILSpec;
  120.     specs = (ResSpec *)(*gUTILSpec + sizeof(short));
  121.     for (i = 0; i < numOwned; i++) {
  122.         /* Copy one owned resource */
  123.         if (idDelta && specs[i].type == ALRTTYPE || specs[i].type == DLOGTYPE) {
  124.             UseResFile(gUTILRef);
  125.             res = Get1Resource(specs[i].type,specs[i].id);
  126.             if (!res) return(false);
  127.             GetResInfo(res,&anID,&aType,name);
  128.             attribs = GetResAttrs(res);
  129.             DetachResource(res);
  130.             
  131.             /* Renumber resource references within ALRTs and DLOGs (ONLY!!!) */
  132.             if (aType == ALRTTYPE) {
  133.                 /* Renumber only if it was in our old resource ID space */
  134.                 itemsID = (*((AlertTemplate **)res))->itemsID;
  135.                 if (itemsID >= curSpace && itemsID < curSpace + UTILSPACESIZE)
  136.                     (*((AlertTemplate **)res))->itemsID += idDelta;
  137.             } else {
  138.                 /* Renumber only if it was in our old resource ID space */
  139.                 itemsID = (*((DialogTemplate **)res))->itemsID;
  140.                 if (itemsID >= curSpace && itemsID < curSpace + UTILSPACESIZE)
  141.                     (*((DialogTemplate **)res))->itemsID += idDelta;
  142.             }
  143.             
  144.             UseResFile(gLWFURef);
  145.             HNoPurge(res);
  146.             AddResource(res,aType,specs[i].id + idDelta,name);
  147.             WriteResource(res);
  148.             SetResAttrs(res,attribs);
  149.         } else if (!CopyResource(gUTILRef,gLWFURef,specs[i].type,specs[i].id,idDelta))
  150.             return(false);
  151.     }
  152.     HUnlock(gUTILSpec); HPurge(gUTILSpec);
  153.     
  154.     /* Update the LWFU resource file */
  155.     UpdateResFile(gLWFURef);
  156.  
  157.     return(true);
  158. }
  159.  
  160. /***************************************************************************************/
  161. void SuperviseInstall(void)
  162. {
  163.     Handle    existingUTIL,newUTIL;
  164.     short    ID,anID,err = noErr;
  165.     ResType    aType;
  166.     Str255    name;
  167.     long    alertUp;
  168.     
  169.     ShowWindow(gUpdating);
  170.     DrawDialog(gUpdating);
  171.     alertUp = TickCount();
  172.     gLWFURef = OpenRFPerm(gLWFUReply.fName,gUTILReply.vRefNum,fsRdWrPerm);
  173.     if (gLWFURef != -1) {
  174.         UseResFile(gUTILRef);
  175.         newUTIL = Get1Resource(UTILTYPE,gUTILID);
  176.         GetResInfo(newUTIL,&anID,&aType,name);
  177.         
  178.         UseResFile(gLWFURef);
  179.         
  180.         existingUTIL = Get1NamedResource(UTILTYPE,name);
  181.         if (existingUTIL)
  182.             err = ALREADYTHERE;
  183.         
  184.         if (!err) {
  185.             /* Figure what UTIL ID to use */
  186.             ID = gUTILID;
  187.             existingUTIL = Get1Resource(UTILTYPE,ID);
  188.             while (existingUTIL)
  189.                 existingUTIL = Get1Resource(UTILTYPE,++ID);
  190.             
  191.             /* ID now holds the first available UTIL ID */
  192.             err = InstallUTIL(ID) ? noErr : BADINSTALL;
  193.         }
  194.         
  195.         /* Close open files */
  196.         CloseResFile(gUTILRef);
  197.         CloseResFile(gLWFURef);
  198.         UseResFile(gAppRef);
  199.         
  200.         /* Put up an alert if necessary */
  201.         if (err)
  202.             ErrorAlert(err);
  203.         else {
  204.             /* Give user reassuring delay */
  205.             if (TickCount() - alertUp < 120)
  206.                 Delay(120L,&alertUp);
  207.             NoteAlert(SUCCESSALRTID,nil);
  208.         }
  209.     } else ErrorAlert(NOOPENLWFU);
  210. }
  211.  
  212. /***************************************************************************************/
  213. Boolean CheckUTIL(void)
  214. {
  215.     ResType    type;
  216.     Str255    name;
  217.     Boolean    retVal = false;
  218.     
  219.     gAppRef = CurResFile();
  220.     gUTILRef = OpenRFPerm(gUTILReply.fName,gUTILReply.vRefNum,fsRdPerm);
  221.     if (gUTILRef != -1) {
  222.         if (CountResources(UTILSPECTYPE) == 1) {
  223.             /* One UTIL per file, please */
  224.             gUTILSpec = GetIndResource(UTILSPECTYPE,1);
  225.             if (gUTILSpec) {
  226.                 GetResInfo(gUTILSpec,&gUTILID,&type,name);
  227.                 if (GetResource(UTILTYPE,gUTILID))
  228.                     retVal = true;
  229.                 else ErrorAlert(NOUTIL);
  230.             } else ErrorAlert(NOUTILSPEC);
  231.         } else ErrorAlert(BADFORMAT);
  232.     } else ErrorAlert(NOOPENUTIL);
  233.     
  234.     /* Leave the file open only if the check was successful */
  235.     if (!retVal)
  236.         CloseResFile(gUTILRef);
  237.  
  238.     return(retVal);
  239. }
  240.  
  241. /***************************************************************************************/
  242. pascal Boolean LWFUFSFilter(HFileParam *pb)
  243. {
  244.     if (pb->ioFlFndrInfo.fdCreator == LWFUCREATOR && !(pb->ioFlAttrib & BUSYATTRIB))
  245.         return(false);
  246.     else return(true);
  247. }
  248.  
  249. /***************************************************************************************/
  250. Boolean FindFiles(void)
  251. {
  252.     SFTypeList    types;
  253.     Point        where;
  254.     DialogPtr    locate;
  255.     Str255        desc;
  256.     GrafPtr        oldPort;
  257.     Boolean        retVal = false;
  258.     
  259.     GetPort(&oldPort);
  260.     
  261.     /* Put up "please locate..." dialog */
  262.     locate = GetNewDialog(LOCATEDLOGID,nil,(WindowPtr)-1);
  263.  
  264.     if (locate) {
  265.         /* Set it up to say "Please locate LWFU" */
  266.         SetPort(locate);
  267.         GetIndString(desc,INSTALLSTRSID,LOCATELWFU);
  268.         ParamText(desc,gEmptyStr,gEmptyStr,gEmptyStr);
  269.         
  270.         /* Show window, note where to put the SF dialog */
  271.         ShowWindow(locate); DrawDialog(locate);
  272.         where.h = locate->portRect.left;
  273.         where.v = locate->portRect.bottom + BOTTOMOFFSET;
  274.         LocalToGlobal(&where);
  275.         
  276.         /* Locate the LaserWriter Font Utility */
  277.         types[0] = 'APPL';
  278.         SFGetFile(where,gEmptyStr,(FileFilterProcPtr)LWFUFSFilter,1,
  279.             types,nil,&gLWFUReply);
  280.  
  281.         /* If they didn't cancel, locate UTIL file */
  282.         if (gLWFUReply.good) {
  283.             /* Set up locate description to say "Please locate UTIL" */
  284.             SetPort(locate);
  285.             GetIndString(desc,INSTALLSTRSID,LOCATEUTIL);
  286.             ParamText(desc,gEmptyStr,gEmptyStr,gEmptyStr);
  287.             DrawDialog(locate);
  288.             
  289.             /* Locate the UTIL file */
  290.             types[0] = 'UTIL';
  291.             SFGetFile(where,gEmptyStr,nil,1,types,nil,&gUTILReply);
  292.             if (gUTILReply.good)
  293.                 retVal = true;
  294.         }
  295.         
  296.         DisposDialog(locate);
  297.     }
  298.     
  299.     SetPort(oldPort);
  300.     return(retVal);
  301. }
  302.  
  303. /***************************************************************************************/
  304. void UTILInstall(void)
  305. {
  306.     if (Alert(ABOUTALRTID,nil) == ok) {            /* Put up the spash screen */
  307.         gUpdating = GetNewDialog(UPDATINGDLOGID,nil,(WindowPtr)-1);
  308.         if (FindFiles())                        /* Locate LWFU and UTIL file */
  309.             if (CheckUTIL())                    /* Check out the UTIL file */
  310.                 SuperviseInstall();                /* Install if all is well */
  311.         DisposDialog(gUpdating);
  312.     }
  313. }
  314.  
  315. /***************************************************************************************/
  316. main()
  317. {
  318.     SysEnvRec    env;
  319.  
  320.     if (Init(&env))
  321.         UTILInstall();                            /* Knock yourself out! */
  322.     else ErrorAlert(BADENV);
  323. }
  324.